eslint-plugin-importのno-extraneous-dependenciesがYarn PnPでうまく動作しないとき
tl;dr
code:.eslintrc.js
module.exports = {
...
settings: {
...
"import/internal-regex": /^@types\//,
"import/external-module-folders": ".yarn" }
...
}
プロダクションに入るコードはdependenciesしか使ってないぞということを強制できるので、安心して{npm,yarn} install --productionしたりnpm pruneしたりできる
しかしこのルール、yarnのPnPを使うとうまく動かず、一切エラーを報告してくれない。 なんで?
実装みる
import/external-module-foldersってなに?
moduleが"external"であるかの判定に使ってるらしい
code:js
if (importType(name, context) !== 'external') {
return;
}
判定条件は?
import/external-module-foldersを使ってるとこ
code:importType.js
function isExternalPath(name, settings, path, packagePath) {
if (internalScope && new RegExp(internalScope).test(name)) {
return false;
}
if (!path || relative(packagePath, path).startsWith('..')) {
return true;
}
return folders.some((folder) => {
const folderPath = nodeResolve(packagePath, folder);
const relativePath = relative(folderPath, path);
return !relativePath.startsWith('..');
});
}
要するにそこ起点で解決したパスの親になれるものを選べばいいらしい
$ yarn node
require.resolve("react") --> /home/tosuke/.../.yarn/cache/react-npm-0.0.0-experimental-2bf4805e4-b45e82adb7-90db4fd2b7.zip/node_modules/react/index.js
.yarn/cacheにしようと思ったが、virtual directoryとして.yarn/__virtual__が指定されてるので.yarnにする
うごいた
続編
eslint-import-resolver-typescriptを使ってると、@types(DefinitelyTyped)系のパッケージをimportしてることにされてエラーになる
@typesはdevDepsなので
PnPでなければexternal-module-foldersにnode_modules/@typesを追加して解決している なんでこんなことになってるのかと言うと、この挙動が回避不可能だから
なんでだよ
internal-regexという設定がeslint-plugin-importにあるので、これで無理やりextraneous-dependenciesの判定から外す
"import/internal-regex": /^@types\//